package com.ideal.hadoopadmin.service.cluster.user;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ideal.hadoopadmin.api.yarn.YarnAPI;
import com.ideal.hadoopadmin.common.entity.ResultAPI;
import com.ideal.hadoopadmin.common.framework.orm.SearchFilter;
import com.ideal.hadoopadmin.entity.cluster.ClusterUser;
import com.ideal.hadoopadmin.entity.cluster.user.Queue;
import com.ideal.hadoopadmin.mapper.webdb.cluster.user.QueueMapper;
import com.ideal.hadoopadmin.service.cluster.ClusterMachineService;
import com.ideal.hadoopadmin.service.cluster.ClusterUserService;
import com.ideal.hadoopadmin.service.cluster.ParameterService;
import com.ideal.tools.scheduler.DbFairSchedulerTools;
import com.ideal.tools.ssh.common.CommonProperties;
import com.ideal.tools.ssh.context.ClusterContext;
import com.ideal.tools.ssh.entity.ContextResult;
import com.ideal.tools.ssh.entity.FairScheduler;
import com.ideal.tools.ssh.entity.LinuxMachine;
import com.ideal.tools.ssh.result.LinuxResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by 袁颖 on 2016/2/29.
 */
@Service
public class QueueService {
    @Resource
    private QueueMapper queueMapper;
    @Resource
    private ParameterService parameterService;
    @Resource
    private ClusterMachineService clusterMachineService;
    @Resource
    ClusterUserService clusterUserService;

    public Queue findById(Long id) {
        return queueMapper.findById(id);
    }

    public List<Queue> findByUserId(Long userId) {
        return queueMapper.findByUseId(userId);
    }

    public Long saveOrUpdate(Queue queue) {
        if (queue.getId() != null) {
            //更新
            queue.setModifyTime(System.currentTimeMillis());
            queueMapper.update(queue);
        } else {
            queue.setModifyTime(System.currentTimeMillis());
            queueMapper.save(queue);
        }
        return queue.getId();
    }

    //新增或者修改队列
    public List<String> editQueue(Queue queue) {
        List<String> messageList = new ArrayList<String>();
        saveOrUpdate(queue);
        messageList.add("<div>数据库信息:保存队列成功!</div>");
        //注释掉旧方法，调用新方法update20160802qinfengxia
        //List<LinuxResult> linuxResults = editeQueueAPI(queue);
        List<LinuxResult> linuxResults = editeQueueAPINew(queue);
        ResultAPI.initAPIResult(linuxResults);
        messageList.addAll(ResultAPI.messageList);
        return messageList;
    }

    public ClusterContext initQueueAPI(Queue queue) {
        ClusterUser clusterUser = clusterUserService.queryClusterUserById(queue.getUserId());
        List<Queue> queues = new ArrayList<Queue>();
        queues.add(queue);
        Map<String, String> parameterMap = parameterService.getAllParameter();
        List<LinuxMachine> linuxMachines = clusterMachineService.getMachineList(null);
        CommonProperties commonProperties = new CommonProperties(parameterMap);
        //获去对应的参数
        List<FairScheduler> fairSchedulerQueues = getFairSchedulerQueues(queues, clusterUser);
        commonProperties.setObjParamter(DbFairSchedulerTools.FAIR_SCHEDULER_QUEUE_LIST, fairSchedulerQueues);
        ClusterContext context = new ClusterContext(commonProperties);
        context.setOriginalList(linuxMachines);
        return context;
    }

    public Map<String, Object> initQueueAPINew(Queue queue) {
        ClusterUser clusterUser = clusterUserService.queryClusterUserById(queue.getUserId());
        List<Queue> queues = new ArrayList<Queue>();
        queues.add(queue);
        //获去对应的参数
        List<FairScheduler> fairSchedulerQueues = getFairSchedulerQueues(queues, clusterUser);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(DbFairSchedulerTools.FAIR_SCHEDULER_QUEUE_LIST, fairSchedulerQueues);
        return params;
    }

    public List<LinuxResult> editeQueueAPI(Queue queue) {
        ClusterContext context = initQueueAPI(queue);
        YarnAPI.dbFairScheduler(context);
        return null == context.getContextResult()?new ArrayList<LinuxResult>():context.getContextResult().getLastResult();
    }

    public List<LinuxResult> editeQueueAPINew(Queue queue) {
        Map<String, Object> params = initQueueAPINew(queue);
        ContextResult contextResult = com.ideal.hadoopadmin.api.better.yarn.YarnAPI.FairScheduler(params);
        return contextResult.getLastResult();
    }
    //检查队列是否冲突
    public boolean checkQueue(Queue queue) {
        Queue oldQueue = queueMapper.findByNameAddUser(queue.getQueueName(), queue.getUserId(), queue.getId());
//        Queue oldQueue = queueMapper.findByNameAddUser(queue.getQueueName(), null);
        if (oldQueue != null && !queue.getId().equals(oldQueue.getId())) {
            return true;//冲突
        }
        return false;
    }

    public PageInfo queryQueueList(Map<String, Object> searchParams, HttpServletRequest request) {
        int currentPage = Integer.parseInt(request.getParameter("page") == null ? "1" : request.getParameter("page"));
        //过滤器
        String where = SearchFilter.parseToString(searchParams);
        //使用分页
        PageHelper.startPage(currentPage, 10);
        //加入组织好的where 条件
        PageHelper.setAppendWhere(where);
        List<Queue> metaHdfsInfoList = queueMapper.queryQueueList();
        PageInfo pageInfo = new PageInfo(metaHdfsInfoList);
        return pageInfo;
    }

    /**
     * 查询所有的队列名
     */
    public List<String> findQueue(Long clusterUserId) {
        List<String> queues = new ArrayList<String>();
        if (clusterUserId == null) {
            queues = queueMapper.findAllQueue();
        } else {
            queues = queueMapper.findQueueByUsername(clusterUserId);
        }
        return queues;
    }

    /**
     * 根据条件查询队列信息
     */
    public List<Queue> queryFairSchedulerAllocationListByDown(Long clusterId, String queue) {
        List<Queue> metaHdfsInfoList = queueMapper.queryQueueBySearchParam(clusterId, queue);
        return metaHdfsInfoList;
    }

    public void saveQueuesDB(List<Queue> queues, Long userId) {
        for (Queue queue : queues) {
            queue.setUserId(userId);
            queueMapper.save(queue);
        }
    }

    public List<String> delQueue(Long id) {
        List<String> messageList = new ArrayList<String>();
        Queue queue = queueMapper.findById(id);
        delQueue(id);
        messageList.add("<div>数据库信息:删除队列成功!</div>");
        //注释掉旧方法，调用新方法update20160802qinfengxia
        //List<LinuxResult> linuxResults = editeQueueAPI(queue);
        List<LinuxResult> linuxResults = editeQueueAPINew(queue);
        ResultAPI.initAPIResult(linuxResults);
        messageList.addAll(ResultAPI.messageList);
        return messageList;
    }

    public void delQueueDB(Long id) {
        queueMapper.deleteById(id);
    }

    //根据数据库中的queue表前台传入的队列集合转换成api所需要的集合
    public List<FairScheduler> getFairSchedulerQueues(List<Queue> queues, ClusterUser clusterUser) {
        //获取所有的队列
        List<Queue> queueList = queueMapper.queryQueueList();
        if (queues != null) {
            queueList.addAll(queues);
        }
        List<FairScheduler> fairSchedulers = new ArrayList<FairScheduler>();
        for (Queue queue : queueList) {
            FairScheduler fairScheduler = new FairScheduler();
            fairScheduler.setId(queue.getId());
            if (queue.getClusterUser() == null) {
                fairScheduler.setUsername(clusterUser.getUserName());
            } else {
                fairScheduler.setUsername(queue.getClusterUser().getUserName());
            }
            fairScheduler.setQueue(queue.getQueueName());
            fairScheduler.setMinMemory(Integer.parseInt(queue.getMinResource().toString()));
            fairScheduler.setMaxMemory(Integer.parseInt(queue.getMaxResource().toString()));
            fairScheduler.setMaxApps(Integer.parseInt(queue.getMaxApp().toString()));
            fairScheduler.setAcl(queue.getAcl());
            fairScheduler.setMinCpu(Integer.parseInt(queue.getMinCpu().toString()));
            fairScheduler.setMaxCpu(Integer.parseInt(queue.getMaxCpu().toString()));
            fairScheduler.setWeight(queue.getWeight());
            fairSchedulers.add(fairScheduler);
        }
        return fairSchedulers;
    }

}
